#include "strHandler.hpp"

#include <iostream>
#include <string>
#include <cstring>
#include <string.h>
using std::string;
using namespace str;

namespace str
{

    string strip(string &str, const string &aim)
    {
        rstrip(str, aim);
        lstrip(str, aim);
        return str;
    }

    string rstrip(string &str, const string &aim)
    {
        while (str.rfind(aim) != string::npos)
        {
            if (str.rfind(aim) + aim.size() != str.size())
            {
                break;
            }
            str.replace(str.rfind(aim), aim.size(), "");
        }
        return str;
    }

    string lstrip(string &str, const string &aim)
    {
        while (str.find(aim) != string::npos)
        {
            if (str.find(aim) != 0)
            {
                break;
            }
            str.replace(0, aim.size(), "");
        }
        return str;
    }

    string replace(string &str, const string &before, const string &after)
    {
        while (str.find(before) != string::npos)
        {
            str.replace(str.find(before), before.size(), after);
        }
        return str;
    }

    // string replaceNum(string& str,const string& aim);
    // string replaceAlpha(string& str,const string& aim);
    // string replacePunct(string& str,const string& aim);

    string lower(string &str)
    {
        for (int i = 0; i < str.size(); ++i)
        {
            if (isupper(str[i]))
            {
                str[i] += 'a' - 'A';
            }
        }
        return str;
    }

    string upper(string &str)
    {
        for (int i = 0; i < str.size(); ++i)
        {
            if (islower(str[i]))
            {
                str[i] -= 'a' - 'A';
            }
        }
        return str;
    }

    string swapcase(string &str)
    {
        for (int i = 0; i < str.size(); ++i)
        {
            if (islower(str[i]))
            {
                str[i] -= 'a' - 'A';
            }
            else if (isupper(str[i]))
            {
                str[i] += 'a' - 'A';
            }
        }
        return str;
    }

    string del(string &str, const string &aim)
    {
        while (str.find(aim) != string::npos)
        {
            str.replace(str.find(aim), aim.size(), "");
        }
        return str;
    }

    int count(string &str, const string &aim)
    {
        int cnt = 0;
        int pos = 0;
        string tmp(str.begin() + pos, str.end());
        while (tmp.find(aim) != string::npos)
        {
            ++cnt;
            tmp = string(tmp.begin() + tmp.find(aim) + aim.size(), tmp.end());
        }

        return cnt;
    }

    vector<string> split(const string &str, const string &delim)
    {
        vector<string> res;
        int pos = 0;
        string in = str;
        rstrip(in, delim);
        in += delim;
        string least(in.begin() + pos, in.end());

        while (least.find(delim) != string::npos)
        {
            string cut(least.begin(), least.begin() + least.find(delim));
            res.push_back(cut);
            pos += cut.size() + delim.size();
            least = string(in.begin() + pos, in.end());
        }

        return res;
    }

}; // namespace str
